import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query, Req, UsePipes } from '@nestjs/common';
import { BaseController } from '../../base/base.controller';
import { DbService } from '@app/db';
import { Lang } from '@app/db/common/entities/Lang';
import { FindOptionsWhere } from 'typeorm';
import { PageDto, AddDto, EditDto } from './dto';
import { DtoPipe } from '../../pipes/dto/dto.pipe';

@Controller('lang')
export class LangController extends BaseController {
    constructor(
        private readonly db:DbService,
    ){
        super()
    }

    @Get()
    async list(@Req() { locale }) {
        return this.successRes(await this.db.lang.find(null, {code : true, values : ['ZH']}, null, null, {sort : 'ASC', id : 'DESC'}))
    }

    @Get('page')
    async rolePage(@Query() dto:PageDto) {
        let result:PaginationResult<Lang> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<Lang> = {
            
        }

        if(dto.code) {
            where.code = dto.code
        }

        result.total = await this.db.lang.count(where)

        if(result.total > 0) {
            result.rows = await this.db.lang.pagination(dto.pageNo, dto.pageSize, where, ['id', 'code', 'sort', 'values'], {sort : 'ASC', id : 'DESC'})
        }
        

        return this.successRes(result)

    }

    @Post('add')
    async add(@Body(new DtoPipe({skipMissingProperties : false})) dto:AddDto, @Req() { locale }) {
        if(true == await this.db.lang.isExistsByWhere({code : dto.code})) {
            return this.failRes(this.i18n.t(locale, 'codeIsExists'))
        }

        dto.createTime = this.utils.time()

        const res = await this.db.lang.insert(dto)
        return res ? this.successRes() : this.failRes()
    }

    @Put('edit/:id')
    async edit(@Body(new DtoPipe()) dto:EditDto, @Param('id', ParseIntPipe) id:number, @Req() { locale }) {
        if(id <= 0) return
        

        let fields = Object.keys(dto) as (keyof Lang)[]
        if(fields.length == 0) return

        const lang = await this.db.lang.findOne({ id }, fields)
        
        if(!lang) return

        let updateData:KeyToValueType<Lang> = {}


        for(let k in lang) {
            if(lang[k] != dto[k]) {
                updateData[k] = dto[k]
            }
        }

        if(Object.keys(updateData).length == 0) return this.successRes()

        if(updateData.code && (true == await this.db.lang.isExistsByWhere({code : updateData.code}))) {
            return this.failRes(this.i18n.t(locale, 'codeIsExists'))
        }

        const res = await this.db.lang.update({id : id}, updateData)
        return res === 0 ? this.failRes() : this.successRes()
    }

    @Delete('delete/:id')
    async delete(@Param('id', ParseIntPipe) id:number) {
        if(id <= 0) return
        const res = await this.db.lang.delete({id : id})
        return res === 0 ? this.failRes() : this.successRes()
    }
}

